package com.study.rabbitmq2.basic1;

import com.rabbitmq.client.*;
import com.study.rabbitmq2.util.ConnectionUtil;

import java.io.IOException;

/**
 * @Author chenyeqing
 * @Date 2021/11/20 20:45
 */
public class Recv {

    private final static String QUEUE_NAME = "simple_queue";

    public static void main(String[] args) {
        // 1、获取连接
        Connection connection = ConnectionUtil.getConnection();
        Channel channel = null;
        try {
            // 2、创建会话通道，生产者和MQ服务所有通信都在channel通道中完成
            channel = connection.createChannel();
        } catch (IOException e) {
            e.printStackTrace();
        }

        try {
            // 3、声明队列
            /**
             * 参数明细：
             * 1、queue：队列名称
             * 2、durable：是否持久化。如果持久化，MQ重启后队列还在
             * 3、exclusive：是否独占连接，队列只允许在该连接中访问，如果connection连接关闭队列则自动删除。
             *      如果将此参数设置为true可用于临时队列的创建
             * 4、autoDelete：是否自动删除，队列不再使用时是否自动删除此队列。
             *      如果将此参数和 exclusive 参数设置为true就可以实现临时队列
             * 5、arguments：参数，可以设置一个队列的扩展参数，比如：可设置存活时间
             */
            channel.queueDeclare(QUEUE_NAME, false, false, false, null);
        } catch (IOException e) {
            e.printStackTrace();
        }

        // 4、实现消费方法
        DefaultConsumer consumer = new DefaultConsumer(channel) {
            @Override
            public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
                System.out.println("start");
                int a = 3 / 0;

                // 交换机
                String exchange = envelope.getExchange();
                // 消息id，mq在channel上用来表示消息的id，可用于确认消息已接收
                long deliveryTag = envelope.getDeliveryTag();
                // body 即消息体
                String msg = new String(body, "utf-8");
                System.out.println("[x] received:" + msg + "!");
            }
        };

        // 监听队列，第二个参数：是否自动进行消息确认
        try {
            /**
             * 参数明细：
             * 1、queue 队列名称
             * 2、autoAck 自动回复，当消费者接收到消息后要告诉MQ消息已接收。
             *      如果将此参数设置为true，表示会自动回复mq；
             *      如果设置为false，要通过编程实现回复
             * 3、callback 消费方法，当消费者接收到消息要执行的方法
             */
            channel.basicConsume(QUEUE_NAME, true, consumer);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
